/***********************************************
 This file is part of redia-lib-utils-ios
.
 
 Copyright (c) 2014 Redia A/S
 
 Redia-library-app-ios is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.
 
 Redia-library-app-ios is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with redia-library-app-ios.  If not, see <http://www.gnu.org/licenses/>.
 
 *********************************************** */

#import "UrlDownloadManager.h"
#import "UrlCacheManager.h"

typedef enum {
    MediaTypeUnknown = 0,
    MediaTypeImage = 1,
    MediaTypeVideo = 2
} MediaType;

@interface UrlDownloadManager()<UrlCacheEntryDelegate>{
    MediaType mMediaType;
    NSSet* mURLs;
    NSInteger mNumerCompleted;
    NSInteger mNumerTotal;
}

@property (nonatomic, strong) void (^downloadProgressBlock)(NSInteger, NSInteger);
@property (nonatomic, strong) void (^downloadCompletionBlock)();
@property (nonatomic, strong) void (^downloadErrorBlock)(NSURL*);

@property (nonatomic, strong) UrlDownloadManager* downloadManager;

@property (nonatomic, strong) NSMutableArray* downloadQueue;
@property (nonatomic, strong) NSMutableSet* sucessfullDownloads;
@property (nonatomic, strong) NSMutableSet* failedDownloads;

@end

@implementation UrlDownloadManager

-(id)initWithMediaType:(MediaType)mediaType andURLs:(NSArray*)urls{
    self = [super init];
    if (self) {
        mMediaType = mediaType;
        mURLs = [NSSet setWithArray:urls];
        self.sucessfullDownloads = [NSMutableSet new];
        self.failedDownloads = [NSMutableSet new];
        self.downloadManager = self;
    }
    return self;
}

-(void)prepareForDealloc{
    self.downloadManager = nil;
    self.downloadProgressBlock = nil;
    self.downloadCompletionBlock = nil;
    self.downloadErrorBlock = nil;
}

-(void)startDownload{
    self.downloadQueue = mURLs.allObjects.mutableCopy;
    self.sucessfullDownloads = [NSMutableSet new];
    self.failedDownloads = [NSMutableSet new];
    mNumerTotal = self.downloadQueue.count;
    mNumerCompleted = 0;
    [self performSelector:@selector(fetchNextURL) withObject:nil afterDelay:0];
    [self performSelector:@selector(fetchNextURL) withObject:nil afterDelay:1];
}

-(void)fetchNextURL{
    if (self.downloadProgressBlock) {
        self.downloadProgressBlock(mNumerCompleted,mNumerTotal);
    }
    if (self.downloadQueue.count == 0) {
        if ((self.sucessfullDownloads.count + self.failedDownloads.count) == mURLs.count) {
            if (self.downloadCompletionBlock) {
                self.downloadCompletionBlock();
                [self prepareForDealloc];
            }
        }
        return;
    }
    NSURL* nextItem = [self.downloadQueue lastObject];
    [self.downloadQueue removeLastObject];
    if (mMediaType == MediaTypeImage) {
        [[UrlCacheManager instance] loadImageUrl:nextItem delegate:self doDownloadOnly:YES];
    } else if (mMediaType == MediaTypeVideo){
        [[UrlCacheManager instance] loadVideoUrl:nextItem delegate:self];
    }
}

- (void)dealloc
{
    DLog(@"UrlDownloadManager dealloc")
}

+(UrlDownloadManager*)loadVideos:(NSArray*)videoURLs
                        progress:(void (^)(NSInteger part, NSInteger total))progressBlock
                      completion:(void (^)())completionBlock
                           error:(void (^)(NSURL* failingURL))errorBlock{
    UrlDownloadManager* urlDownloadManager = [[UrlDownloadManager alloc] initWithMediaType:MediaTypeVideo andURLs:videoURLs];
    urlDownloadManager.downloadProgressBlock = progressBlock;
    urlDownloadManager.downloadCompletionBlock = completionBlock;
    urlDownloadManager.downloadErrorBlock = errorBlock;
    [urlDownloadManager startDownload];
    return urlDownloadManager;
}

+(UrlDownloadManager*)loadImages:(NSArray*)imageURLs
                        progress:(void (^)(NSInteger part, NSInteger total))progressBlock
                      completion:(void (^)())completionBlock
                           error:(void (^)(NSURL* failingURL))errorBlock{
    UrlDownloadManager* urlDownloadManager = [[UrlDownloadManager alloc] initWithMediaType:MediaTypeImage andURLs:imageURLs];
    urlDownloadManager.downloadProgressBlock = progressBlock;
    urlDownloadManager.downloadCompletionBlock = completionBlock;
    urlDownloadManager.downloadErrorBlock = errorBlock;
    [urlDownloadManager startDownload];
    return urlDownloadManager;
}

#pragma mark UrlCacheEntryDelegate
-(void)cacheEntry:(UrlCacheEntry*)cacheEntry didLoadObjectFromUrl:(NSURL*)url ofType:(UrlCacheEntryType)type{
    mNumerCompleted++;
    [self.sucessfullDownloads addObject:url];
    [self fetchNextURL];
}

-(void)cacheEntry:(UrlCacheEntry*)cacheEntry didFailOnUrl:(NSURL*)url error:(NSError*)error{
    mNumerCompleted++;
    if (self.downloadErrorBlock) {
        self.downloadErrorBlock(url);
    }
    [self.failedDownloads addObject:url];
    [self fetchNextURL];
}
@end
